package com.dubbo.auth.configuration;

import com.dubbo.auth.shiro.CustomRealm;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;

@Configuration
public class ShiroConfig {

    @Autowired
    private ShiroConfiguration shiroConfiguration;

    @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Optional.ofNullable(shiroConfiguration.getLoginUrl()).ifPresent(e->shiroFilterFactoryBean.setLoginUrl(shiroConfiguration.getLoginUrl()));
        Optional.ofNullable(shiroConfiguration.getUnauthorizedUrl()).ifPresent(e->shiroFilterFactoryBean.setUnauthorizedUrl(shiroConfiguration.getUnauthorizedUrl()));
        Optional.ofNullable(shiroConfiguration.getSuccessUrl()).ifPresent(e->shiroFilterFactoryBean.setSuccessUrl(shiroConfiguration.getSuccessUrl()));
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        // anon:所有url都都可以匿名访问
        shiroConfiguration.getAnonList().stream().forEach(e->{
            Optional.ofNullable(e).ifPresent(m->filterChainDefinitionMap.put(e, "anon"));
        });
        // authc:所有url都必须认证通过才可以访问
        shiroConfiguration.getAuthcList().stream().forEach(e->{
            Optional.ofNullable(e).ifPresent(m->filterChainDefinitionMap.put(e, "authc"));
        });
        //主要这行代码必须放在所有权限设置的最后，不然会导致所有 url 都被拦截 剩余的都需要认证
        filterChainDefinitionMap.put("/**", "authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;

    }


    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();
        defaultSecurityManager.setRealm(customRealm());
        return defaultSecurityManager;
    }

    @Bean
    public CustomRealm customRealm() {
        CustomRealm customRealm = new CustomRealm();
        return customRealm;
    }

}
